﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using Icoders.MarketTracker.Core.MasterData;
using Icoders.MarketTracker.Core.Repository.MasterDataRepositories;
using Icoders.MarketTracker.Core.Validation;
using Icoders.MarketTracker.Data.EF;
using Icoders.MarketTracker.Data.Utils;
using Icoders.MarketTracker.Data.Utils.Caching;

namespace Icoders.MarketTracker.Data.Repository.MasterDataRepositories
{
   public class FrsAssignRepository :RepositoryBase, IFrsAssignRepository
    {
        private AppDataContext _ctx;
       private IClientRepository _iClientRepository;
       private IZoneRepository _iZoneRepository;
       private ICountryRepository _iCountryRepository;
       private ICacheProvider _cacheProvider;

       public FrsAssignRepository(AppDataContext ctx, IClientRepository iClientRepository, IZoneRepository iZoneRepository, ICountryRepository iCountryRepository, ICacheProvider cacheProvider)
       {
           _ctx = ctx;
           _iClientRepository = iClientRepository;
           _iZoneRepository = iZoneRepository;
           _iCountryRepository = iCountryRepository;
           _cacheProvider = cacheProvider;
       }

       public int Save(FrsAssign entity)
       {
           ValidationResultInfo vri = Validate(entity);
           if(!vri.IsValid)
           {
               throw new DomainValidationException(vri, "FrsAssign Details provided not Valid");
           }
           DateTime date = TimeUtil.GetDateTime();
           TblFrsAssign tbl= _ctx.TblFrsAssign.FirstOrDefault(s => s.UserId == entity.UserId);
           if (tbl == null)
           {
               tbl = new TblFrsAssign();
               tbl.CreatedOn = date;
               tbl.StatusId = (int) MasterEntityStatus.New;
               _ctx.TblFrsAssign.AddObject(tbl);
           }else
           {
                tbl.StatusId = (int)MasterEntityStatus.Updated;
           }
          
           tbl.ClientId = entity.ClientId;
           tbl.UserId = entity.UserId;
           tbl.AreaId = entity.AreaId;
           tbl.UpdatedOn = date;
           tbl.MondayZone = entity.MondayZone;
           tbl.TuesdayZone = entity.TuesdayZone;
           tbl.WednesdayZone = entity.WednesdayZone;
           tbl.ThursdayZone = entity.ThursdayZone;
           tbl.FridayZone = entity.FridayZone;
           tbl.SaturdayZone = entity.SaturdayZone;
           tbl.SundayZone = entity.SundayZone;
           tbl.Target = entity.Target;
           _ctx.SaveChanges();
           _cacheProvider.Put(_cacheListKey, _ctx.TblFrsAssign.Where(x => x.StatusId != 3).Select(s => s.Id).ToList());
           _cacheProvider.Remove(string.Format(_cacheKey, tbl.Id));
           return tbl.Id;
       }

       public FrsAssign GetById(int id)
       {
           FrsAssign entity = (FrsAssign)_cacheProvider.Get(string.Format(_cacheKey, id));
           if (entity == null)
           {
               var tbl = _ctx.TblFrsAssign.FirstOrDefault(s => s.Id == id);
               if (tbl != null)
               {
                   entity = Map(tbl);
                   _cacheProvider.Put(string.Format(_cacheKey, entity.Id), entity);
               }

           }
           return entity;
       }

       public List<FrsAssign> GetAll()
       {
           //return _ctx.TblFrsAssign.ToList().Where(p => p.StatusId != (int)MasterEntityStatus.Deleted).Select(n => Map(n)).ToList();
           IList<FrsAssign> entities = null;
           IList<int> ids = (IList<int>)_cacheProvider.Get(_cacheListKey);
           if (ids != null)
           {
               entities = new List<FrsAssign>(ids.Count);
               foreach (int id in ids)
               {
                   FrsAssign entity = GetById(id);
                   if (entity != null)
                       entities.Add(entity);
               }
           }
           else
           {
               entities = _ctx.TblFrsAssign.Where(x => x.StatusId != 3).ToList().Select(s => Map(s)).ToList();
               if (entities != null && entities.Count > 0)
               {
                   ids = entities.Select(s => s.Id).ToList(); //new List<int>(persons.Count);
                   _cacheProvider.Put(_cacheListKey, ids);
                   foreach (FrsAssign p in entities)
                   {
                       _cacheProvider.Put(string.Format(_cacheKey, p.Id), p);
                   }

               }
           }
           return entities.ToList();
       }

       public void Delete(int userid)
       {
           var tbl = _ctx.TblFrsAssign.FirstOrDefault(s => s.UserId == userid);
           if (tbl != null)
           {
               tbl.StatusId = (int)MasterEntityStatus.Deleted;
               _ctx.SaveChanges();
               _cacheProvider.Put(_cacheListKey, _ctx.TblFrsAssign.Where(x => x.StatusId != 3).Select(s => s.Id).ToList());
               _cacheProvider.Remove(string.Format(_cacheKey, tbl.Id));
           }
       }

       public FrsAssign GetByUser(int userId)
       {
           //var tbl = _ctx.TblFrsAssign.FirstOrDefault(s => s.UserId == userId);
           //if (tbl == null) return null;
           //return Map(tbl);
           return GetAll().FirstOrDefault(s => s.UserId == userId);
       }

       public List<int> GetZoneAssigned(int userId)
       {
           List<int> ids = new List<int>();
           FrsAssign assign = GetByUser(userId);
           if(assign!=null)
           {
               if (assign.MondayZone != 0)
                   ids.Add(assign.MondayZone);
               if (assign.TuesdayZone != 0)
                   ids.Add(assign.TuesdayZone);
               if (assign.WednesdayZone != 0)
                   ids.Add(assign.WednesdayZone);
               if (assign.ThursdayZone != 0)
                   ids.Add(assign.ThursdayZone);
               if (assign.FridayZone != 0)
                   ids.Add(assign.FridayZone);
               if (assign.SaturdayZone != 0)
                   ids.Add(assign.SaturdayZone);
               if (assign.SundayZone != 0)
                   ids.Add(assign.SundayZone);
           }
           ;
           return ids;
       }

       private FrsAssign Map(TblFrsAssign tblFrsAssign)
       {
           return new FrsAssign()
                      {
                          Id = tblFrsAssign.Id,
                          MondayZone = tblFrsAssign.MondayZone.Value,
                          TuesdayZone = tblFrsAssign.TuesdayZone.Value,
                          WednesdayZone = tblFrsAssign.WednesdayZone.Value,
                          ThursdayZone = tblFrsAssign.ThursdayZone.Value,
                          FridayZone = tblFrsAssign.FridayZone.Value,
                          SaturdayZone = tblFrsAssign.SaturdayZone.Value,
                          SundayZone = tblFrsAssign.SundayZone.Value,
                          UpdatedOn = tblFrsAssign.UpdatedOn,
                          CreatedOn = tblFrsAssign.CreatedOn,
                          UserId = tblFrsAssign.UserId,
                          AreaId = tblFrsAssign.AreaId,
                          ClientId = tblFrsAssign.ClientId,
                          ClientName = tblFrsAssign.TblClient.Name,
                          AreaName = tblFrsAssign.TblArea.Name,
                          Username = tblFrsAssign.TblUser.Username,
                          Target=tblFrsAssign.Target,
                          ZoneMonday = _ctx.TblZone.Where(s=>s.Id==tblFrsAssign.MondayZone.Value).Select(s=>s.Name).First(),// _iZoneRepository.GetbyName(tblFrsAssign.MondayZone.Value).Name,
                          ZoneTuesday =_ctx.TblZone.Where(s=>s.Id==tblFrsAssign.TuesdayZone.Value).Select(s=>s.Name).First(),// _iZoneRepository.GetbyName(tblFrsAssign.TuesdayZone.Value).Name,
                          ZoneWednesday =_ctx.TblZone.Where(s=>s.Id==tblFrsAssign.WednesdayZone.Value).Select(s=>s.Name).First(),// _iZoneRepository.GetbyName(tblFrsAssign.WednesdayZone.Value).Name,
                          ZoneThursday = _ctx.TblZone.Where(s => s.Id == tblFrsAssign.ThursdayZone.Value).Select(s => s.Name).First(),// _iZoneRepository.GetbyName(tblFrsAssign.ThursdayZone.Value).Name,
                          ZoneFriday = _ctx.TblZone.Where(s => s.Id == tblFrsAssign.FridayZone.Value).Select(s => s.Name).First(),// _iZoneRepository.GetbyName(tblFrsAssign.FridayZone.Value).Name,
                          ZoneSaturday = _ctx.TblZone.Where(s => s.Id == tblFrsAssign.SaturdayZone.Value).Select(s => s.Name).First(),// _iZoneRepository.GetbyName(tblFrsAssign.SaturdayZone.Value).Name,
                          ZoneSunday = _ctx.TblZone.Where(s => s.Id == tblFrsAssign.SundayZone.Value).Select(s => s.Name).First(),//_iZoneRepository.GetbyName(tblFrsAssign.SundayZone.Value).Name,
                          Status = (MasterEntityStatus)tblFrsAssign.StatusId

                      };
       }

       public ValidationResultInfo Validate(FrsAssign objToValidate)
       {
           ValidationResultInfo vri = objToValidate.BasicValidation();
           //bool hasDuplicateUserId = GetAll().Where(v => v.Id != objToValidate.Id)
           //    .Any(p => p.UserId == objToValidate.UserId);
           //if (hasDuplicateUserId)
           //    vri.Results.Add(new ValidationResult("Duplicate User Found"));
           return vri;
       }

       protected override string _cacheKey
       {
           get { return "FSRAssign-{0}"; }
       }

       protected override string _cacheListKey
       {
           get { return "FSRAssignList"; }
       }
    }
}
